;
; core-docs.scm
;
; Provide documentation for all the functions implemented in C++ code.
; These can be viewed the guile interpreter prompt by saying
;
;    guile> ,describe  FUNCTION-NAME
;
; A list of all of these is printed by saying
;
;    guile> ,apropos cog
;
(set-procedure-property! cog-new-atom 'documentation
"
 cog-new-atom ATOM [ATOMSPACE]
    If the optional ATOMSPACE argument is provided, copy the existing
    ATOM into ATOMSPACE; otherwise copy it into the current AtomSpace
    for this thread.

    Use (cog-atomspace ATOM) to examine the AtomSpace that the ATOM
    is currently in.

    Example:
        ; Create a new Atom in the current AtomSpace.
        guile> (define ca (Concept \"A\"))

        ; What AtomSpace is it in?
        guile> (cog-atomspace ca)

        ; Create a new AtomSpace, and put an atom into it.
        guile> (define spacex (cog-new-atomspace))
        guile> (define xca (cog-new-atom ca spacex))
        guile> (cog-atomspace xca)

        ; Print AtomSpace contents
        guile> (cog-prt-atomspace)
        guile> (cog-prt-atomspace spacex)
")

(set-procedure-property! cog-new-node 'documentation
"
 cog-new-node NODE-TYPE NODE-NAME
    Create a new Node of Type NODE-TYPE and name NODE-NAME.

    Throws errors if NODE-TYPE is not a valid Atom Type for a Node,
    and if NODE-NAME is not a string. Use (cog-get-types) to get a
    list of the currently loaded atom types.

    Example:
        ; Create a new node, and prints its value:
        guile> (cog-new-node 'Concept \"some node name\")
        (ConceptNode \"some node name\")
")

(set-procedure-property! cog-node 'documentation
"
 cog-node NODE-TYPE NODE-NAME [ATOMSPACE]
    Returns the Node of Type NODE-TYPE and name NODE-NAME, if it exists,
    else returns null.

    If an optional ATOMSPACE is specified, then it is queried for the
    node, instead of the current AtomSpace for this thread.

    Throws errors if NODE-TYPE is not a valid atom type for a Node,
    and if NODE-NAME is not a string. Use (cog-get-types) to get a
    list of the currently loaded atom types.

    Example:
        ; Check to see if a node exists:
        guile> (cog-node 'Concept \"asdf\")
        #f

        ; Now, create the node, and see if it exists:
        guile> (cog-new-node 'Concept \"asdf\")
        (ConceptNode \"asdf\")
        guile> (cog-node 'Concept \"asdf\")
        (ConceptNode \"asdf\")
")

(set-procedure-property! cog-new-link 'documentation
"
 cog-new-link LINK-TYPE ATOM-1 ... ATOM-N
    Create a new Link, of Type LINK-TYPE, holding the given Atoms.

    Throws errors if LINK-TYPE is not a valid Link Type, or if any of
    the arguments after the Link Type are not Atoms or AtomSpaces.
    Use (cog-get-types) to get a list of the currently loaded atom types.

    Example:
        ; Creates two nodes, and a new link:
        guile> (define x (Concept \"abc\"))
        guile> (define y (Concept \"def\"))
        guile> (cog-new-link 'Link x y)
        (Link
           (ConceptNode \"abc\")
           (ConceptNode \"def\")
        )
")

(set-procedure-property! cog-link 'documentation
"
 cog-link LINK-TYPE ATOM-1 ... ATOM-N [ATOMSPACE]
    Returns the Link of the given type LINK-TYPE and list of atoms,
    if it exists, else returns null.

    If an optional ATOMSPACE is specified, then it is queried for the
    link, instead of the current AtomSpace for this thread.

    Throws errors if LINK-TYPE is not a valid Link Type, or if any
    of the arguments after the Link Type are not Atoms or AtomSpaces.
    Use (cog-get-types) to get a list of the currently loaded atom types.

    Example:
        ; Create two nodes:
        guile> (define x (cog-new-node 'ConceptNode \"abc\"))
        guile> (define y (cog-new-node 'ConceptNode \"def\"))

        ; Does a node with these two links exist?
        guile> (cog-link 'Link x y)
        ()

        ; Now, create such a link
        guile> (cog-new-link 'Link x y)
        (Link
           (ConceptNode \"abc\")
           (ConceptNode \"def\")
        )

        ; Check again for existence:
        guile> (cog-link 'Link x y)
        (Link
           (ConceptNode \"abc\")
           (ConceptNode \"def\")
        )
")

(set-procedure-property! cog-extract! 'documentation
"
 cog-extract! ATOM [ATOMSPACE]
    Remove the indicated ATOM, but only if it has no incoming links.
    If it has incoming links, the remove fails.

    Returns #t if the atom was removed, else returns #f if not removed.

    This does NOT remove the atom from any attached persistent storage.
    Use cog-delete! from the (opencog persist) module to remove atoms
    from storage.

    Use cog-extract-recursive! to force removal of this atom, together
    with any links that might be holding this atom.

    If the optional ATOMSPACE argument is provided, then the ATOM is
    removed from that AtomSpace; otherwise, it is removed from the
    current AtomSpace for this thread.

    Example:
       ; Define two nodes and a link between them:
       guile> (define x (Concept \"abc\"))
       guile> (define y (Concept \"def\"))
       guile> (define l (Link x y))

       ; Verify that there's an atom called x:
       guile> x
       (ConceptNode \"abc\")

       ; Try to extract x. This should fail, since there's a link
       ; containing x.
       guile> (cog-extract! x)
       #f

       ; Delete x, and everything pointing to it. This should extract
       ; both x, and the link l.
       guile> (cog-extract-recursive! x)
       #t

       ; Verify that the link l is gone:
       guile> l
       Invalid handle

       ; Verify that the node x is gone:
       guile> x
       Invalid handle

       ; Verify that the node y still exists:
       guile> y
       (ConceptNode \"def\")
")

(set-procedure-property! cog-extract-recursive! 'documentation
"
 cog-extract-recursive! ATOM [ATOMSPACE]
    Remove the indicated ATOM, and all atoms that point at it.
    Return #t on success, else return #f if not removed.

    This does NOT remove the atom from any attached persistent storage.
    Use cog-delete-recursive! from the (opencog persist) module to
    remove atoms from storage.

    If the optional ATOMSPACE argument is provided, then the ATOM is
    removed from that AtomSpace; otherwise, it is removed from the
    current AtomSpace for this thread.

    See also: cog-extract!
")

(set-procedure-property! cog-atom 'documentation
"
 cog-atom ATOM [ATOMSPACE]
    Return #f if ATOM is not in the current AtomSpace, or, if the
    optional argument ATOMSPACE is given, then if it is not in that.
    If it is present, then return ATOM.

    Example:
       ; Define a node.
       guile> (define x (Concept \"abc\"))
       guile> (cog-atom x)
       #t
       guile> (cog-push-atomspace)
       guile> (define y (Concept \"def\"))
       guile> (cog-pop-atomspace)
       ; Now, y is an Atom, but it is not in any AtomSpace.
       guile> (cog-atom? y)
       #t
       guile> (cog-atom y)
       #f

    See also:
       cog-atom? -- return #t if an expression is an Atom.
")

(set-procedure-property! cog-atom? 'documentation
"
 cog-atom? EXP
    Return #t if EXP is an atom, else return #f

    Example:
       ; Define a node.
       guile> (define x (Concept \"abc\"))
       guile> (define y (+ 2 2))
       guile> (cog-atom? x)
       #t
       guile> (cog-atom? y)
       #f

    See also:
       cog-atom -- return #f if an Atom is not in the current AtomSpace.
")

(set-procedure-property! cog-node? 'documentation
"
 cog-node? EXP
    Return #t if EXP is an node, else return #f

    See also cog-node, which will check to see if a specific node
    already exists.

    Example:
       ; Define a node and a link
       guile> (define x (Concept \"abc\"))
       guile> (define y (ListLink x))
       guile> (cog-node? x)
       #t
       guile> (cog-node? y)
       #f
")

(set-procedure-property! cog-link? 'documentation
"
 cog-link? EXP
    Return #t if EXP is an link, else return #f

    See also cog-link, which will check to see if a specific link
    already exists.

    Example:
       ; Define a node and a link
       guile> (define x (Concept \"abc\"))
       guile> (define y (ListLink x))
       guile> (cog-link? x)
       #f
       guile> (cog-link? y)
       #t
")

(set-procedure-property! cog-name 'documentation
"
 cog-name ATOM
    Return the name of the node ATOM. If the atom is not a node,
    returns null.

    Example:
       ; Define a node
       guile> (define x (Concept \"abc\"))
       guile> (cog-name x)
       \"abc\"
")

(set-procedure-property! cog-number 'documentation
"
 cog-number NUMBER-NODE
    Return the (list of) floating point values of NUMBER-NODE.
    The NUMBER-NODE must be an Node of type NumberNode, else an
    exception will be thrown.

   This is the same as saying (string->number (cog-name NUMBER-NODE))

    Example:
       ; Define a node
       guile> (define x (cog-new-node 'NumberNode 42))
       guile> (cog-number x)
       42.0
")

(set-procedure-property! cog-type 'documentation
"
 cog-type EXP
    Return the type of EXP, where EXP is a Value or an Atom.
    The returned value is a guile symbol.

    Example:
       ; Define a node
       guile> (define x (Concept \"abc\"))
       guile> (cog-type x)
       ConceptNode
       guile> (eq? 'ConceptNode (cog-type x))
       #t

    See also:
        cog-value-type ATOM KEY -- get the type of the value at KEY on ATOM.
        cog-subtype? TYPE SUBTYPE -- return #t if SUBTYPE is a TYPE
        cog-link-type? TYPE -- return #t if TYPE is a Link type
        cog-node-type? TYPE -- return #t if TYPE is a Node type
        cog-value-type? TYPE -- return #t if TYPE is a Value type
")

(set-procedure-property! cog-arity 'documentation
"
 cog-arity ATOM
    Return the arity of ATOM.

    Example:
       guile> (define x (Concept \"abc\"))
       guile> (cog-arity x)
       0
       guile> (define l (Link x x x))
       guile> (cog-arity l)
       3
")

(set-procedure-property! cog-incoming-set 'documentation
"
 cog-incoming-set ATOM [ATOMSPACE]
    Return the incoming set of ATOM.  This set is returned as an
    ordinary scheme list.

    If the optional argument ATOMSPACE is given, then the lookup is
    performed in that AtomSpace. This is useful when the Atom appears
    in more than one AtomSpace, and it's incoming set differs in each
    space.  If the optional argument is not given, then the current
    AtomSpace is used.

    See also: cog-incoming-size, cog-incoming-by-type

    Example:
       ; Define two nodes and a link between them:
       guile> (define x (Concept \"abc\"))
       guile> (define y (Concept \"def\"))
       guile> (define l (Link x y))

       ; Get the incoming sets of nodes x and y (which is the link l):
       guile> (cog-incoming-set x)
       ((Link
          (ConceptNode \"abc\")
          (ConceptNode \"def\")
       )
       )

       guile> (cog-incoming-set y)
       ((Link
          (ConceptNode \"abc\")
          (ConceptNode \"def\")
       )
       )

       ; Verify that the both incoming sets are really one and the
       ; same link:
       guile> (equal? (cog-incoming-set x) (cog-incoming-set y))
       #t

       ; The returned values are lists, and not singleton atoms.
       ; Thus, the incoming set of x is a list containing l:
       guile> (equal? (cog-incoming-set x) (list l))
       #t

       ; Verify that the returned value is a true list:
       guile> (list? (cog-incoming-set x))
       #t
")

(set-procedure-property! cog-incoming-size 'documentation
"
 cog-incoming-size ATOM [ATOMSPACE]
    Return the number of atoms in the incoming set of ATOM.

    If the optional argument ATOMSPACE is given, then the lookup is
    performed in that AtomSpace. This is useful when the Atom appears
    in more than one AtomSpace, and it's incoming set differs in each
    space.  If the optional argument is not given, then the current
    AtomSpace is used.

    See also: cog-incoming-set, cog-incoming-size-by-type

    Example:
       ; Define two nodes and a link between them:
       guile> (define x (Concept \"abc\"))
       guile> (define y (Concept \"def\"))
       guile> (Link x y)

       ; Get the size of the incoming set of nodes x and y:
       guile> (cog-incoming-size x)
       => 1

       guile> (cog-incoming-size y)
       => 1
")

(set-procedure-property! cog-incoming-by-type 'documentation
"
 cog-incoming-by-type ATOM TYPE [ATOMSPACE]
    Return the incoming set of ATOM that consists only of atoms of
    type TYPE.  This set is returned as an ordinary scheme list.

    If the optional argument ATOMSPACE is given, then the lookup is
    performed in that AtomSpace. This is useful when the Atom appears
    in more than one AtomSpace, and it's incoming set differs in each
    space.  If the optional argument is not given, then the current
    AtomSpace is used.

    Example:
       ; Define two nodes and two links between them:
       guile> (define x (Concept \"abc\"))
       guile> (define y (Concept \"def\"))
       guile> (ListLink x y)
       guile> (UnorderedLink x y)

       ; Get all ListLinks that x appears in:
       guile> (cog-incoming-by-type x 'ListLink)
       ((ListLink
          (ConceptNode \"abc\")
          (ConceptNode \"def\")
       )
       )

       ; Get all UnorderedLinks that x appears in:
       guile> (cog-incoming-by-type x 'UnorderedLink)
       ((UnorderedLink
          (ConceptNode \"abc\")
          (ConceptNode \"def\")
       )
       )
")

(set-procedure-property! cog-incoming-size-by-type 'documentation
"
 cog-incoming-size-by-type ATOM TYPE [ATOMSPACE]
    Return the number of atoms of type TYPE in the incoming set of ATOM.

    If the optional argument ATOMSPACE is given, then the lookup is
    performed in that AtomSpace. This is useful when the Atom appears
    in more than one AtomSpace, and it's incoming set differs in each
    space.  If the optional argument is not given, then the current
    AtomSpace is used.

    See also: cog-incoming-by-type, cog-incoming-size

    Example:
       ; Define two nodes and a link between them:
       guile> (define x (Concept \"abc\"))
       guile> (define y (Concept \"def\"))
       guile> (ListLink x y)
       guile> (UnorderedLink x y)

       ; Get the number of ListLinks that x appears in:
       guile> (cog-incoming-size-by-type x 'ListLink)
       => 1
")

(set-procedure-property! cog-outgoing-atom 'documentation
"
 cog-outgoing-atom ATOM INDEX
    Return the INDEX'th atom in the outgoing set of ATOM. Indexing
    is done from a base of zero. This returns the same atom as
    (list-ref (cog-outgoing-set ATOM) INDEX) but is faster.
")

(set-procedure-property! cog-outgoing-set 'documentation
"
 cog-outgoing-set ATOM
    Return the outgoing set of ATOM.  This set is returned as an
    ordinary scheme list.
")

(set-procedure-property! cog-outgoing-by-type 'documentation
"
 cog-outgoing-by-type ATOM TYPE
    Return those atoms in the outgoing set of ATOM that are of type TYPE.
    This set is returned as an ordinary scheme list.
")

(set-procedure-property! cog-handle 'documentation
"
 cog-handle ATOM
    Return the hash of ATOM. The hash is a 64-bit integer, computed
    from the component parts of the Atom (but not it's Values), that
    can be used in hash tables or other algorithms that require a hash.
    Links always have the high-bit set, and Nodes never do.

    Example:
       guile> (cog-handle (Concept \"abc\"))
       999283543311182409
")

(set-procedure-property! cog-atom-less? 'documentation
"
 cog-atom-less? L-ATOM R-ATOM
    Return #t if L-ATOM is less than R-ATOM, else return #f.  This
    predicate is useful for creating sorted lists of atoms; for
    example, to rapidly remove duplicate atoms from a long list.

    Example:
       guile> (cog-atom-less? (Concept \"abc\") (Concept \"def\"))
       #f
")

(set-procedure-property! cog-equal? 'documentation
"
 cog-equal? L-ATOM R-ATOM
    Return #t if the contents of L-ATOM and R-ATOM are the same, else
    return #f.  This can be used to compare two atoms in two different
    AtomSpaces for equality. A content-compare is performed, i.e. a
    check is made to see if they have the same name or the same outgoing
    set. The Values hanging off the atoms are NOT compared; they might
    differ.

    Example:
       guile> (define space1 (cog-atomspace))
       guile> (define a1 (Concept \"abc\"))
       guile> (define space2 (cog-new-atomspace))
       guile> (cog-set-atomspace! space2)
       guile> (define a2 (Concept \"abc\"))
       guile> (equal? a1 a2)
       #f
       guile> (cog-equal? a1 a2)
       #t
")

(set-procedure-property! cog-inc-value! 'documentation
"
  cog-inc-value! ATOM KEY CNT REF -- Increment value on ATOM by CNT.

  The REF location of the FloatValue at KEY is atomically incremented
  by CNT.  CNT may be any floating-point number (positive or negative).
  The rest of the FloatValue vector is left untouched.

  If the ATOM does not have any Value at KEY, or if the current Value
  is not a FloatValue, then a new FloatValue of length (REF+1) is
  created. If the existing FloatValue is too short, it is extended
  until it is at least (REF+1) in length.

  The increment is atomic; that is, it is safe against racing threads.

  To increment several locations at once, use the cog-update-value!
  function.

  Example usage:
     (cog-inc-value!
         (Concept \"Question\")
         (Predicate \"Answer\")
         42.0  0)

  See also:
      cog-update-value! -- A generic atomic read-modify-write.
      cog-set-value-ref! - Set one location in a vector.
")

; ===================================================================

(set-procedure-property! cog-new-value 'documentation
"
 cog-new-value TYPE ARGS
    Create a new Value of type TYPE, with additional ARGS. In many
    cases, ARGS is list of strings, floats or values.  The TYPE must
    be a valid Value type; use (cog-get-types) to get a list of the
    currently loaded types.

    Example:
       guile> (cog-new-value 'FloatValue 1 2 3))
       (FloatValue 1.000000 2.000000 3.00000)

       guile> (cog-new-value 'StringValue \"foo\" \"bar\")
       (StringValue \"foo\" \"bar\")

       guile> (cog-new-value 'LinkValue
             (Concept \"foo\") (StringValue \"bar\"))
       (LinkValue
           (ConceptNode \"foo\")
           (StringValue \"bar\")
       )

       guile> (cog-new-value 'Concept \"foo\")
       (ConceptNode \"foo\")
")

(set-procedure-property! cog-keys 'documentation
"
 cog-keys ATOM
    Return a list of all of the keys attached to ATOM. In order to get
    all of the values attached to an atom, one must first find the keys
    that are used to anchor them. This function returns these.

    Example:
       guile> (cog-set-value!
                 (Concept \"abc\") (Predicate \"key\")
                 (FloatValue 1 2 3))
       guile> (cog-keys (Concept \"abc\"))

    See also:
       cog-keys->alist ATOM - return association list of keys+values
       cog-value ATOM KEY - return a value for the given KEY
       cog-value-type ATOM KEY -- get the type of the value at KEY on ATOM.
")

(set-procedure-property! cog-keys->alist 'documentation
"
 cog-keys->alist ATOM
    Return an association list of all key-value pairs attached to ATOM.

    Example:
       guile> (cog-set-value!
                 (Concept \"abc\") (Predicate \"key\")
                 (FloatValue 1 2 3))
       guile> (cog-keys->alist (Concept \"abc\"))

    See also:
       cog-keys ATOM - return list of all keys on ATOM
       cog-value ATOM KEY - return a value for the given KEY
       cog-value-type ATOM KEY -- get the type of the value at KEY on ATOM.
")

(set-procedure-property! cog-value 'documentation
"
 cog-value ATOM KEY
    Return the value of KEY for ATOM. Both ATOM and KEY must be atoms.

    Example:
       guile> (cog-set-value!
                 (Concept \"abc\") (Predicate \"key\")
                 (FloatValue 1 2 3))
       guile> (cog-value (Concept \"abc\") (Predicate \"key\"))
       (FloatValue 1.000000 2.000000 3.00000)

   See also:
       cog-keys ATOM - return list of all keys on ATOM
       cog-value-type ATOM KEY -- get the type of the value at KEY on ATOM.
")

(set-procedure-property! cog-value-type 'documentation
"
 cog-value-type ATOM KEY
    Return the type of the value of KEY for ATOM. Both ATOM and KEY
    must be atoms. The returned type is a guile symbol.

    Example:
       guile> (cog-set-value!
                 (Concept \"abc\") (Predicate \"key\")
                 (FloatValue 1 2 3))
       guile> (cog-value-type (Concept \"abc\") (Predicate \"key\"))
       FloatValue

   See also:
       cog-value ATOM KEY -- get the value at KEY on ATOM.
       cog-keys ATOM - return list of all keys on ATOM.
")

(set-procedure-property! cog-set-value! 'documentation
"
 cog-set-value! ATOM KEY VALUE
    Set the value of KEY for ATOM to VALUE. Both ATOM and KEY must be
    atoms. The VALUE can be any Atomese Value, or #f or the empty list.
    If it is #f or the empty list '(), then the KEY is removed from
    the atom.

    This returns either ATOM or a copy of ATOM with the new value. If
    the current AtomSpace is a copy-on-write (COW) AtomSpace, and ATOM
    lies in some other space below the current space, then a copy of
    ATOM will be made and placed in the current space.  This copy will
    have the new VALUE, while the value on the input ATOM will be
    unchanged.  COW spaces are commonly used with underlying read-only
    spaces, or with long stacks (DAG's) of AtomSpaces (Frames) recording
    a history of value changes.

    Example:
       guile> (cog-set-value!
                 (Concept \"abc\") (Predicate \"key\")
                 (FloatValue 1 2 3))
       guile> (cog-value (Concept \"abc\") (Predicate \"key\"))
       (FloatValue 1.000000 2.000000 3.00000)

       guile> (cog-set-value!
                 (Concept \"abc\") (Predicate \"key\") #f)
       guile> (cog-value (Concept \"abc\") (Predicate \"key\"))
       #f

    See also:
       cog-set-value-ref! - Set one location in a vector.
       cog-inc-value! - Increment one location in a vector.
       cog-update-value! - Perform an atomic read-modify-write
       cog-set-values! - Set multiple values.
       cog-new-atomspace - Create a new AtomSpace
       cog-atomspace-cow! - Mark AtomSpace as a COW space.
       cog-atomspace-ro! - Mark AtomSpace as read-only.
")

(set-procedure-property! cog-set-value-ref! 'documentation
"
  cog-set-value-ref! ATOM KEY VAL REF -- Set location REF of vector
     locatated at KEY on ATOM to VAL.

  The REF location of the vector Value at KEY is set to VAL. The type
  of VAL must be appropriate for the Value stored there: for StringValue
  vectors, VAL must be a string; for FloatValueV vectors, VAL must be a
  float, and so on. The other locations in the  value are left untouched.

  The reference is a zero-based offset from the start of the vector.

  If the ATOM does not have any Value at KEY, then nothing is done.
  If the existing Value is too short, it is extended until it is at
  least (REF+1) in length.

  Example usage:
     (cog-set-value!
         (Concept \"Question\")
         (Predicate \"Answer\")
         (StringValue \"a\" \"b\" \"c\" \"d\" \"e\"))
     (cog-value (Concept \"Question\") (Predicate \"Answer\"))
     (cog-set-value-ref!
         (Concept \"Question\")
         (Predicate \"Answer\")
         \"forty-two\" 3)
     (cog-value (Concept \"Question\") (Predicate \"Answer\"))

  See also:
      cog-update-value! -- A generic atomic read-modify-write.
      cog-set-value-ref! - Set one location in a vector.
")

(set-procedure-property! cog-update-value! 'documentation
"
 cog-update-value! ATOM KEY DELTA
    Perform an atomic read-modify-write update of the value at KEY
    on ATOM, using DELTA to modify the original value.

    At this time, the only updates that are implemented are the
    increment of floating-point Values, such as FloatValues. The
    intended use is for the safe update of counts from multiple
    threads.

    This function is similar to the `cog-inc-value!` function, except
    that it allows a full-vector update. When DELTA is a vector, with
    multiple non-zero entries, all of them are added to the matching
    entries in the Value at KEY. This is a vector-increment.

    The update is atomic; that is, it is safe against racing threads.

    See also:
       cog-inc-value! -- Increment one location in a generic FloatValue
       cog-set-value! -- Set a single value.
       cog-set-values! -- Set multiple values.
       cog-set-value-ref! - Set one location in a vector.
")

(set-procedure-property! cog-set-values! 'documentation
"
 cog-set-values! ATOM ALIST
    Set multiple values on ATOM from the key-value pairs in ALIST.
    The ALIST must be an association list, of the form of
    ((key1 . value1) (key2 . value2) ...)

    Example:
       guile> (cog-set-values!
                 (Concept \"abc\")
                 (list
                    (cons (Predicate \"key1\") (FloatValue 1 2 3))
                    (cons (Predicate \"key2\") (FloatValue 4 5 6))))
       guile> (cog-keys->alist (Concept \"abc\"))

    Keys can also be removed, by setting the value to #f or to '()

    Example:
       guile> (cog-set-values!
                 (Concept \"abc\")
                 (list
                    (cons (Predicate \"key1\") #f)
                    (cons (Predicate \"key2\") #f)))
       guile> (cog-keys->alist (Concept \"abc\"))

    This returns either ATOM or a copy of ATOM with the new value. If
    the current AtomSpace is a copy-on-write (COW) AtomSpace, and ATOM
    lies in some other space below the current space, then a copy of
    ATOM will be made and placed in the current space.  This copy will
    have the new VALUE, while the value on the input ATOM will be
    unchanged.  COW spaces are commonly used with underlying read-only
    spaces, or with long stacks (DAG's) of AtomSpaces (Frames) recording
    a history of value changes.

    See also:
       cog-set-value! ATOM VALUE - Set a single value.
       cog-new-atomspace - Create a new AtomSpace
       cog-atomspace-cow! BOOL - Mark AtomSpace as a COW space.
       cog-atomspace-ro! - Mark AtomSpace as read-only.
")

(set-procedure-property! cog-value? 'documentation
"
 cog-value? EXP
    Return #t if EXP is an OpenCog value, else return #f

    Example:
       guile> (cog-value? (FloatValue 42))
       #t
       guile> (cog-value? 42)
       #f
")

(set-procedure-property! cog-value->list 'documentation
"
 cog-value->list VALUE
    Return a scheme list holding the values in the Atomese VALUE.
    If VALUE is a Link, this returns the outgoing set.
    If VALUE is a Node, this returns list containing the node name.
    If VALUE is a StringValue, FloatValue or LinkValue, this returns
        the associated list of values.

    Example:
       guile> (cog-value->list (FloatValue 0.1 0.2 0.3))
       (0.1 0.2 0.3)
       guile> (cog-value->list (Number 1 2 3))
       (1.0 2.0 3.0)
")

(set-procedure-property! cog-value-ref 'documentation
"
 cog-value-ref VALUE N
 cog-value-ref ATOM KEY N
    The first form returns the N'th entry in the OpenCog VALUE.
    The second form looks up the value om ATOM at KEY, and then returns
    the N'th entry.

    If the value is a Link, this returns the N'th atom in the outgoing set.
        That is, it returns the same atom as cog-outgoing-atom.
    If the value is a Node, and N is zero, this returns the node name.
    If the value is a StringValue, FloatValue or LinkValue, this returns
        the N'th entry in the value.

    The first form returns the same result as
        (list-ref (cog-value->list VALUE) N)

    The second form returns the same result as
        (list-ref (cog-value->list (cog-value ATOM KEY)) N)

    The difference is that this one call will be a lot faster than
    either of the equivalent forms (and thus is suitable for use in
    tight inner loops).

    Example:
       guile> (cog-value-ref (FloatValue 0.1 0.2 0.3) 2)
       0.3
       guile> (cog-value-ref (Number 1 2 3) 2)
       3.0

	See also:
       cog-set-value-ref! - Set one location in a vector.
       cog-inc-value! - Increment one location in a vector.
")

(set-procedure-property! cog-get-types 'documentation
"
 cog-get-types
    Return a list of all of the Atom and Value types in the system.

    Example:
        guile> (cog-get-types)

    See also:
        cog-get-subtypes TYPE -- Return list of immediate subtypes of TYPE.
        cog-get-all-subtypes TYPE -- Return list of all subtypes of TYPE.
")

(set-procedure-property! cog-type->int 'documentation
"
 cog-type->int TYPE
    Return the C++ internal type number assigned to an Atom TYPE.

    This provides access to the type numbering in the current C++
    AtomSpace session. The value is not universally unique, and may
    change from one session to the next. This function is for
    internal use only; do not use in general code.
")

(set-procedure-property! cog-get-subtypes 'documentation
"
 cog-get-subtypes TYPE
    Return a list of the subtypes of the given TYPE.  Only the
    immediate subtypes are returned; to obtain all subtypes, this
    function should be called recursively.

    Example:
        guile> (cog-get-subtypes 'Atom)
        (Link Node)

    See also:
        cog-get-all-subtypes TYPE -- Return list of all subtypes of TYPE.
        cog-get-types -- Return list of all types.
")

(set-procedure-property! cog-subtype? 'documentation
"
 cog-subtype? TYPE SUBTYPE
    Return #t if SUBTYPE is a subtype of TYPE, else return #f.
    The check is performed recursively.

    Example:
        guile> (cog-subtype? 'Node 'Link)
        #f
        guile> (cog-subtype? 'Atom 'Link)
        #t
        guile> (cog-subtype? 'Atom 'ConceptNode)
        #t

    See also:
        cog-type ATOM -- return the type of ATOM
        cog-value-type ATOM KEY -- get the type of the value at KEY on ATOM.
        cog-link-type? TYPE -- return #t if TYPE is a Link type
        cog-node-type? TYPE -- return #t if TYPE is a Node type
        cog-value-type? TYPE -- return #t if TYPE is a Value type
")

(set-procedure-property! cog-map-type 'documentation
"
 cog-map-type PROC TYPE [ATOMSPACE]
    Call procedure PROC for each atom in the ATOMSPACE that is of
    type TYPE. If PROC returns any value other than #f, then the
    iteration is terminated.  Note that this iterates only over the
    given type, and not its sub-types. Thus (cog-map-type PROC 'Atom)
    will never call PROC, because no atoms in the AtomSpace can have
    the type Atom: they are all subtypes of Atom.

    The ATOMSPACE argument is optional; if absent, the default
    AtomSpace for this thread is used.

    Example:
       ; define a function that prints the atoms:
       guile> (define (prt-atom h) (display h) #f)
       guile> (cog-map-type prt-atom 'ConceptNode)

  See also: cog-get-atoms TYPE - returns a list of atoms of TYPE.
")

(set-procedure-property! cog-count-atoms 'documentation
"
  cog-count-atoms ATOM-TYPE [ATOMSPACE] -- Count of number of atoms

  Return a count of the number of atoms of the given type `ATOM-TYPE`.
  If the optional argument `ATOMSPACE` is given, then a count is
  returned for that AtomSpace; otherwise, the default AtomSpace for
  this thread is used.

  Example usage:
     (display (cog-count-atoms 'Concept))
  will display a count of all atoms of type 'Concept

  See also:
     cog-get-atoms -- return a list of all atoms of a given type.
     cog-report-counts -- return a report of counts of all atom types.
")

(set-procedure-property! cog-atomspace 'documentation
"
 cog-atomspace [ATOM]
   If the optional ATOM is specified, then return the AtomSpace of ATOM.
   Otherwise, return the current atomspace for this thread.
")

(set-procedure-property! cog-set-atomspace! 'documentation
"
 cog-set-atomspace! ATOMSPACE
    Set the current atomspace for this thread to ATOMSPACE. Every
    thread has it's own current atomspace, to which all atom-processing
    operations apply.  Returns the previous atomspace for this thread.

    Warning: if the previous atomspace is not the primary atomspace
    and is not referenced anywhere, the garbage collector will delete it
    alongside its content, even if some of its content is referenced.
")

(set-procedure-property! cog-atomspace? 'documentation
"
 cog-atomspace? ATOMSPACE
    Return #t if ATOMSPACE is an atomspace; else return #f.
")

(set-procedure-property! cog-new-atomspace 'documentation
"
 cog-new-atomspace [NAME] [ATOMSPACE [ATOMSPACE2 [...]]]
    Create a new atomspace.  If the optional argument NAME is present,
    and it is a string, then the new AtomSpace will be given this
    name. If a list of AtomeSpaces are present, then the new AtomSpace
    will include these as subframes (subspaces).

    Returns the new atomspace.

    AtomSpaces are automatically deleted when no more references to
    them remain. To prevent this, either keep a guile variable pointing
    to it, or insert it into a Link.

    Note that this does NOT set the current atomspace to the new one;
    to do that, you need to use cog-set-atomspace!

    The name of the AtomSpace can be obtained with `cog-name`.

    See also:
       AtomSpace -- create an AtomSpace and insert it into this one.
       cog-atomspace -- Get the current AtomSpace in this thread.
       cog-atomspace-env -- Get the subspaces.
       cog-atomspace-ro! -- Mark the AtomSpace as read-only.
       cog-atomspace-cow! -- Mark the AtomSpace as copy-on-write.
")

(set-procedure-property! AtomSpace 'documentation
"
 AtomSpace [NAME]
    Create a new AtomSpace; optionally give it the name NAME, and
    insert it into the current AtomSpace.

    See also:
       cog-new-atomspace -- Create a new AtomSpace.
       cog-atomspace -- Get the current AtomSpace in this thread.
")

(set-procedure-property! cog-atomspace-env 'documentation
"
 cog-atomspace-env [ATOMSPACE]
    Return the parent(s) of ATOMSPACE. The ATOMSPACE argument is
    optional; if not specified, the current atomspace is assumed.

    See also:
       cog-atomspace -- Get the current AtomSpace in this thread.
")

(set-procedure-property! cog-push-atomspace 'documentation
"
 cog-push-atomspace -- Create a temporary AtomSpace.

    This creates a new AtomSpace, derived from the current AtomSpace,
    and makes it current. Thus, all subsequent atom operations will
    create Atoms in this new AtomSpace. To delete it, simply pop it;
    after popping, all of the Atoms placed into it will also be
    deleted (unless they are referred to in some way).

    The stack of AtomSpaces is per-thread; a push in one thread does
    not affect the current AtomSpace in other threads. The stack is
    shared with Python, so cross-language push/pop operations work
    correctly.

    Returns the previous (base) AtomSpace.

    See also:
       cog-pop-atomspace -- Delete a temporary AtomSpace.
       cog-set-atomspace! -- Set the current AtomSpace.
")

(set-procedure-property! cog-pop-atomspace 'documentation
"
 cog-pop-atomspace -- Delete a temporary AtomSpace.

    This pops the current AtomSpace from the stack, clears it, and
    removes it from the parent AtomSpace. The previous AtomSpace
    becomes the current one.

    The stack is shared with Python, so cross-language push/pop
    operations work correctly.

    See also:
       cog-push-atomspace -- Create a temporary AtomSpace.
")

(set-procedure-property! cog-atomspace-clear 'documentation
"
 cog-atomspace-clear [ATOMSPACE]
     Extract all atoms from ATOMSPACE. The ATOMSPACE argument is
     optional; if not specified, the current atomspace is assumed.

     This only removes the atoms from the current atomspace frame,
     it does NOT remove them from any attached storage. Use the
     `delete-frame!` function to remove frames from storage.

     Note that removing a frame may cause Atoms in lower frames to
     become visible! This is because `absent` atoms are used to hide
     Atoms in lower layers; when these are removed, the lower atoms
     become visible.
")

(set-procedure-property! cog-atomspace-ro! 'documentation
"
 cog-atomspace-ro! [ATOMSPACE]
     Mark the ATOMSPACE as being read-only. New atoms cannot be added
     to a read-only atomspace, nor can atoms be removed. The Values
     of atoms in the read-only atomspace cannot be changed.

     The ATOMSPACE argument is optional; if not specified, the current
     atomspace is assumed.

     See also: cog-atomspace-rw!, cog-atomspace-readonly?,
         cog-atomspace-cow! and cog-atomspace-cow?
")

(set-procedure-property! cog-atomspace-rw! 'documentation
"
 cog-atomspace-rw! [ATOMSPACE]
     Mark the ATOMSPACE as being read-write. See cog-atomspace-ro!
     for a detailed explanation.

     The ATOMSPACE argument is optional; if not specified, the current
     atomspace is assumed.

     See also: cog-atomspace-readonly?, cog-atomspace-cow! and
         cog-atomspace-cow?
")

(set-procedure-property! cog-atomspace-readonly? 'documentation
"
 cog-atomspace-readonly? [ATOMSPACE]
     Return #t if the ATOMSPACE is marked read-only. See
     cog-atomspace-ro! for a detailed explanation.

     The ATOMSPACE argument is optional; if not specified, the current
     atomspace is assumed.

     See also: cog-atomspace-cow! and cog-atomspace-cow?
")

(set-procedure-property! cog-atomspace-cow! 'documentation
"
 cog-atomspace-cow! BOOL [ATOMSPACE]
     Set the copy-on-write (COW) bit on the ATOMSPACE to BOOL.

     A COW atomspace behaves as if the parent has been marked read-only,
     and so any modifications to atoms in a COW space do not affect the
     parent. (It does not make sense to mark an atomspace as being COW,
     if there is no parent.)

     The ATOMSPACE argument is optional; if not specified, the current
     atomspace is assumed.

     COW spaces are useful as temporary or transient AtomSpaces, so that
     scratch calculations and updates can be performed without affecting
     the parent.

     Long chains of COW spaces can also be used to record a history of
     changes to Values stored on Atoms. This can be useful in several
     ways, including backtracking from complex inferences.

     Atoms that are deleted in COW spaces are removed only in that
     space; they remain in the parent AtomSpaces. They can also be
     added back in, farther up a stack of spaces.

     See also: cog-atomspace-cow?, cog-atomspace-readonly?,
         cog-atomspace-ro! and cog-atomspace-rw!,
")

(set-procedure-property! cog-atomspace-cow? 'documentation
"
 cog-atomspace-cow? [ATOMSPACE]
     Return the copy-on-write (COW) bit on the ATOMSPACE to BOOL.
     See cog-atomspace-cow! for an explanation.

     The ATOMSPACE argument is optional; if not specified, the current
     atomspace is assumed.

     See also: cog-atomspace-ro! and cog-atomspace-rw! and
         cog-atomspace-readonly?,
")

(set-procedure-property! cog-set-server-mode! 'documentation
"
 cog-set-server-mode! BOOL
     If BOOL is #t, then some server-freindly options are enabled,
     including the high-precision printing of FloatValues. Otherwise,
     human-friendly shell-evaluator style is used. The default is
     false. Returns the previous setting.
")

;set-procedure-property! cog-yield 'documentation
;"
; cog-yield
;    The implementation uses a simple exception mechanism to allow
;    scheme code to return to the guile prompt from anywhere. To use
;    this, simply throw 'cog-yield from anywhere.  The catch handler
;    will promptly return to the cogserver.  This can be used with
;    continuations to implement some simple multi-threading.
;
;    Example:
;       guile> (throw 'cog-yield \"hello world\")
;       (hello world)
;")
